package com.gitee.chenyaohua.common;

import com.gitee.chenyaohua.antlr.JSON5Lexer;
import com.gitee.chenyaohua.antlr.JSON5Parser;
import com.gitee.chenyaohua.ext.Json5ResolveVisitor;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.TokenStream;

import java.io.Serializable;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public abstract class JSON {

    public static List<Object> parseArray(String text){

        JsonNode<?> jsonNode = getJsonNode(text);

        return (List<Object>) conver(jsonNode);
    }

    public static Map<Serializable,Object> parseObject(String text){

        JsonNode<?> jsonNode = getJsonNode(text);

        return (Map<Serializable,Object>) conver(jsonNode);
    }

    private static Object conver(JsonNode<?> jsonNode){
        switch (jsonNode.getNodeype()) {
            case ARRAY:
                ArrayNode node = (ArrayNode) jsonNode;
                List<JsonNode<?>> data = node.getData();
                List<Object> list = new LinkedList<>();
                for (JsonNode<?> datum : data) {
                    Object conver = conver(datum);
                    list.add(conver);
                }
                return list;
            case OBJECT:
                ObjectNode objectNode = (ObjectNode) jsonNode;
                HashMap<Serializable,Object> hashMap = new HashMap<>();
                for (Map.Entry<Serializable, JsonNode<?>> entry : objectNode.getData().entrySet()) {
                    Serializable key = entry.getKey();
                    JsonNode<?> value = entry.getValue();
                    hashMap.put(key,conver(value));
                }
                return hashMap;
            default:
                return jsonNode.getData();
        }
    }

    private static JsonNode<?> getJsonNode(String text){
        CharStream charStream = CharStreams.fromString(text);
        JSON5Lexer json5Lexer = new JSON5Lexer(charStream);
        TokenStream tokenStream = new CommonTokenStream(json5Lexer);
        JSON5Parser json5Parser = new JSON5Parser(tokenStream);
        Json5ResolveVisitor visitor = new Json5ResolveVisitor();
        JsonNode<?> visit = visitor.visit(json5Parser.json5());
        return visit;
    }
}
